Datadog のAWS監視にIAMロールを利用してみた
はじめに
AWSチームのすずきです。
監視SaaSとして知られるDatadog、AWSのCloudwatch、CloudTrailの監視を行う AWS Integrationは、IAMロールを利用して監視対象の情報を取得します。
今回、DatadogのAWSアカウントをクロスアカウントアクセスの許可先としたIAMロールを作成し、 Datadog のAWS Integration (Role Delegation)を実施する設定について、紹介させて頂きます。
※ AWS Integration は、中国とGovCloudを除き、IAMロールの設定が必須となりました。(2017年5月追記)
設定
Datadogの公式ドキュメントに準じ、AWS Integration、CloudTrail Integration の設定を行います。
外部IDの発行
- Datadog AWS Integration の設定画面を開きます。
- AWSアカウントの設定画面を開き、AWS External IDを確認します。
IAMロールの作成
- AWS コンソール、IAMロール画面より「新しいロールの作成」を実行します
- ロール名は、公式ドキュメントに準じ「DatadogAWSIntegrationRole」とします
- ロールタイプの選択としてクロスアカウントアクセスのロールを指定し、「サードパーティの AWS アカウントの IAM ユーザーに、アカウントへのアクセスを許可します。」を選択します。
- 信頼性の確立で、DatadogのAWSアカウント(464622532012)を記入します。
- 外部IDは、DatadogのAWS Integration画面で確認したAWS External IDを記入します
- MFAが必要のオプションはチェックしません。
- 詳細なポリシーを後ほど作成して利用するので、管理ポリシーのアタッチは実施せず、次に進みます。
- 作成したIAMロール「DatadogAWSIntegrationRole」の変更画面を開きます。
- Datadogが必要とするIAM権限、インラインポリシーで反映します。
- カスタムポリシーを指定し、PolicyEditorの使用を選択します
- ポリシー名は「DatadogAWSIntegrationPolicy」
- ポリシードキュメントには 公式ドキュメント記載のJSONを反映します。
- DatadogAWSIntegrationPolicy (2017/5時点)
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "autoscaling:Describe*", "budgets:ViewBudget", "cloudtrail:DescribeTrails", "cloudtrail:GetTrailStatus", "cloudwatch:Describe*", "cloudwatch:Get*", "cloudwatch:List*", "dynamodb:list*", "dynamodb:describe*", "ec2:Describe*", "ec2:Get*", "ecs:Describe*", "ecs:List*", "elasticache:Describe*", "elasticache:List*", "elasticloadbalancing:Describe*", "elasticmapreduce:List*", "elasticmapreduce:Describe*", "es:ListTags", "es:ListDomainNames", "es:DescribeElasticsearchDomains", "kinesis:List*", "kinesis:Describe*", "logs:Get*", "logs:Describe*", "logs:FilterLogEvents", "logs:TestMetricFilter", "rds:Describe*", "rds:List*", "route53:List*", "s3:GetBucketTagging", "s3:ListAllMyBuckets", "ses:Get*", "sns:List*", "sns:Publish", "sqs:ListQueues", "support:*" ], "Effect": "Allow", "Resource": "*" } ] }
- CloudTrail Integrationを利用するため、S3に保管されているログを参照するためのポリシーを、DatadogAWSIntegrationRoleに付与します。
- CloudTrailのログ保管先のS3バケット「cloudtrail-<リージョン>-<アカウントID>」、「cloudtrail-*」にcloudtrail用途以外のバケットは無いものとして設定しました。可能であればログ保管先のS3バケット名は明示し、Datadogが参照可能なS3を限定して利用される事をお勧めします。
-
DatadogAWSCloudTrailReadOnlyAccessPolicy
{ "Statement": [ { "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:GetObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::cloudtrail-*" ] } ] }
- ロールARNの確認
- アカウントIDと、ロール名を確認します。
Datadog アカウント設定
- AWS Account ID と、ロール名を記入します。
- ロール情報入力後、「Account credentials are valid」と有効性が確認出来ない場合には、記入情報を見直します
- External IDが変更となった場合、IAMロール(DatadogAWSIntegrationRole)の信頼関係の編集で、Condition→StringEquals→sts:ExternalIdの値を差し替えます。
- Datadogを監視対象台数に応じた有償ライセンスで利用する場合、「Optionally limit metrics collection」→ 「To hosts with tag:」を設定し、監視対象のEC2インスタンスを限定する事をお薦めします。
- 「To hosts with tag: datadog-enable:true」とする事で、EC2のタグとして「キー:datadog-enable、値: true」と明示したインスタンスのみが、EC2監視の対象となります。
動作確認
- AWS Integrationの設定後、30分〜1時間後位をめどに確認を実施します。
AWS Integrationのメトリック
- DatadogのMetrics→Summary画面より「aws」、AWS Integrationのメトリックを確認します
- ロールを追加したアカウントに該当する項目をタグなどで選択し、グラフ表示を確認します。
監視ホスト数
- Datadogの課金、監視対象となったEC2台数に応じて発生します。(Proの場合、1台月額18$)
- Datadogの管理画面より、「Usage」を開き、監視対象のホスト数が意図した台数であるか確認します。
アクセスキーの撤去
- 過去にDatadogで利用していたアクセスキーが存在する場合、意図せぬ利用を回避するためアクセスキーの撤去、無効化をお薦めします。
- アクセスキーを発行したIAMユーザを選択し、アクセスキーの管理を開きます。
- ステータス欄が「Active」なキーを「無効化」、または「削除」します。
- Datadog専用のIAMユーザを作成されていた場合には、IAMユーザごとの撤去がお勧めです。
まとめ
IAMアクセスキーを利用する場合、アクセスキー、シークレットキーが悪意をもった第三者に漏れた場合の対策を 常に意識することが必要でした。
適切なクロスアカウントアクセス設定を施したIAMロールの利用により、キーが不正利用されるリスクを大きく軽減でき、 シークレットキーの隠匿や、定期的なアクセスキー、シークレットキーの更新運用などからも開放されます。
今回、DatadogのAWS IntegrationでもIAMロールの利用が可能となりました。 新規導入の環境だけでなく、従来のアクセスキーを登録されている環境も、 IAMロールによる認証 (Role Delegation) へ切り替える事をおすすめします。
参考
CloudFormation
- Datadog用のIAMロールを作成するテンプレートを用意しました。
- Datadogが示す「AWS External ID」を、CloudFormationのパラメータとして指定する事で、Datadog用のロールを作成する事が可能です。
- Datadogに反映する設定値(ロール名)は、CreateStack実行後、Outputsで確認可能です
- YAML版
AWSTemplateFormatVersion: '2010-09-09' Parameters: DatadogExternalID: Default: ExternalID Description: Datadog AWS External ID Type: String Resources: DatadogAWSIntegrationRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Action: sts:AssumeRole Effect: Allow Condition: StringEquals: sts:ExternalId: !Ref 'DatadogExternalID' Principal: AWS: arn:aws:iam::464622532012:root Path: / DatadogAWSIntegrationPolicy: Type: AWS::IAM::Policy Properties: PolicyName: DatadogAWSIntegration PolicyDocument: Version: '2012-10-17' Statement: - Action: - autoscaling:Describe* - budgets:ViewBudget - cloudtrail:DescribeTrails - cloudtrail:GetTrailStatus - cloudwatch:Describe* - cloudwatch:Get* - cloudwatch:List* - dynamodb:list* - dynamodb:describe* - ec2:Describe* - ec2:Get* - ecs:Describe* - ecs:List* - elasticache:Describe* - elasticache:List* - elasticloadbalancing:Describe* - elasticmapreduce:List* - elasticmapreduce:Describe* - es:ListTags - es:ListDomainNames - es:DescribeElasticsearchDomains - kinesis:List* - kinesis:Describe* - logs:Get* - logs:Describe* - logs:FilterLogEvents - logs:TestMetricFilter - rds:Describe* - rds:List* - route53:List* - s3:GetBucketTagging - s3:ListAllMyBuckets - ses:Get* - sns:List* - sns:Publish - sqs:ListQueues - support:* Effect: Allow Resource: '*' Roles: - !Ref 'DatadogAWSIntegrationRole' DatadogAWSCloudTrailReadOnlyAccessPolicy: Type: AWS::IAM::Policy Properties: PolicyName: DatadogAWSCloudTrailReadOnlyAccess PolicyDocument: Version: '2012-10-17' Statement: - Action: - s3:ListBucket - s3:GetBucketLocation Effect: Allow Resource: '*' - Action: - s3:GetObject Effect: Allow Resource: arn:aws:s3:::cloudtrail-* Roles: - !Ref 'DatadogAWSIntegrationRole' Outputs: RoleName: Description: The IAM Role to share with Datadog (Name) Value: !Ref 'DatadogAWSIntegrationRole' RoleArn: Description: The IAM Role to share with Datadog (ARN) Value: !GetAtt 'DatadogAWSIntegrationRole.Arn' DatadogExternalID: Description: Datadog AWS External ID Value: !Ref 'DatadogExternalID' AwsAccoutID: Description: AWS Account ID Value: !Ref 'AWS::AccountId'